//
//  MUPNotificationController.h
//  MUPFoundation
//
//  Created by hex on 11/10/14.
//  Copyright (c) 2014 ND. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 *  以 Block 方式观察 Notification 时使用的 Block
 *
 *  @param notification 通知
 */
typedef void (^BZNotificationBlock)(NSNotification *notification);


/**
 对 Notification 操作的封装。支持自动移除对通知的观察。
 */
@interface BZNotificationController : NSObject

/**
 *  初始化一个 NotificationController 实例。
 *
 *  @param observer 实际的 Observer
 *
 *  @return 一个 NotificationController 实例
 */
- (instancetype)initWithObserver:(id)observer;

+ (instancetype)controllerWithObserver:(id)observer;


/**
 *  以 Selector 形式观察 Notification
 *
 *  @param name     Notification 的名称
 *  @param object   指定发送的对象。仅有该对象发送的 Notification 被接受。设置为 nil 的话不指定。
 *  @param selector 接受到 Notification 时，发送给 Observer 的消息。可以不含或仅含一个 NSNotification 参数。
 */

- (void)observeNotification:(NSString *)name object:(id)object selector:(SEL)selector;

/**
 *  以 Block 形式观察 Notification，在主线程执行 Block
 *
 *  @param name   Notification 的名称
 *  @param object 指定发送的对象。仅有该对象发送的 Notification 被接受。设置为 nil 的话不指定。
 *  @param block  接受到 Notification 时, 在主线程执行的 Block
 */
- (void)observeNotification:(NSString *)name object:(id)object block:(BZNotificationBlock)block;


/**
 *  以 Block 形式观察 Notification，在主线程执行 Block
 *
 *  @param name   Notification 的名称
 *  @param object 指定发送的对象。仅有该对象发送的 Notification 被接受。设置为 nil 的话不指定。
 *  @param block  接受到 Notification 时, 在主线程执行的 Block
 *  @param queue  Block 执行的线程
 */
- (void)observeNotification:(NSString *)name object:(id)object block:(BZNotificationBlock)block queue:(NSOperationQueue *)queue;

/**
 *  根据 Notification 名称移除观察。
 *  注意：在 Observer 被释放时，所有通知会自动被移除。
 *
 *  @param name Notification 名称，不可为 nil。
 */
- (void)unobserveNotification:(NSString *)name;

/**
 *  根据 Notification 名称移除观察。name 与 object 不能同时为 nil。
 *  注意：在 Observer 被释放时，所有通知会自动被移除。
 *
 *  @param name   Notification 名称。当其为 nil 时，不作为移除的依据。
 *  @param object 发送的对象。当其为 nil 时，不作为移除的依据。
 */
- (void)unobserveNotification:(NSString *)name object:(NSObject *)object;


/**
 *  移除所有该 Observer 观察的通知。
 */
- (void)unobserveAll;

@end


/**
 *  为所有以 NSObject 为父类的对象提供一个 Lazy Loading 的 notificationController 对象。
 */
@interface NSObject (BZNotificationController)

@property (nonatomic, strong) BZNotificationController *notificationController;

@end
